package com.itbupt.domain.strategy.repository;

import com.itbupt.domain.strategy.model.entity.StrategyAwardEntity;
import com.itbupt.domain.strategy.model.entity.StrategyEntity;
import com.itbupt.domain.strategy.model.entity.StrategyRuleEntity;
import com.itbupt.domain.strategy.model.valobj.RuleTreeVO;
import com.itbupt.domain.strategy.model.valobj.RuleWeightVO;
import com.itbupt.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import com.itbupt.domain.strategy.model.valobj.StrategyAwardStockKeyVO;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author dingchang
 * @Date 2025/3/15 21:46
 * @Description: 策略服务仓储接口
 */

public interface IStrategyRepository {

    /**
     * 查询策略奖品列表
     * @param strategyId 策略ID
     * @return 策略奖品 列表
     */
    List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId);


    /**
     * 将概率值保存到redis里面
     * @param strategyId 策略ID
     * @param rateRange 概率范围
     * @param strategyAwardSearchRateTable 索引与 AwardId对应表
     */
    void storeStrategyAwardSearchRateTable(String strategyId, Integer rateRange, Map<Integer, Integer> strategyAwardSearchRateTable);

    /**
     *  通过生成的随机值rateKey，获取概率值奖品查找表的结果
     * @param key 策略ID
     * @param rateKey 随机值
     * @return awardId
     */
    Integer getStrategyAwardAssemble(String key, Integer rateKey);

    /**
     * 获取概率范围----数值范围
     * @param strategyId 策略ID
     * @return
     */
    int getRateRange(Long strategyId);

    int getRateRange(String key);


    /**
     * 查询策略实体信息： 策略描述、规则模型
     * @param strategyId 策略ID
     * @return 策略实体
     */
    StrategyEntity queryStrategyEntityByStrategyId(Long strategyId);

    /**
     * 查询策略规则
     * @param strategyId 策略ID
     * @param ruleModel 权重规则
     * @return
     */
    StrategyRuleEntity queryStrategyRule(Long strategyId, String ruleModel);

    /**
     * 查询策略规则的具体规则值信息ruleValue
     * @param strategyId 策略ID
     * @param awardId 奖品ID
     * @param ruleModel 抽奖规则类型
     * rule_random - 随机值计算
     * rule_lock - 抽奖几次后解锁
     * rule_luck_award - 幸运奖(兜底奖品)
     * @return 规则值RuleValue - 不同的规则模型有不同的规则值
     */
    String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel);

    String queryStrategyRuleValue(Long strategyId, String ruleModel);

    /**
     * 查询策略奖品规则模型
     * @param strategyId 策略ID
     * @param awardId 奖品ID
     * @return 抽奖策略规则规则值对象
     */
    StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Integer awardId);

    /**
     * 根据规则树ID，查询树结构信息
     * @param treeId 规则树ID
     * @return 树的信息
     */
    RuleTreeVO queryRuleTreeVOByTreeId(String treeId);

    /**
     * 缓存奖品库存
     * @param cacheKey 缓存Key - 由策略ID和奖品ID组成
     * @param awardCount 奖品库存值
     */
    void cacheStrategyAwardCount(String cacheKey, Integer awardCount);

    /**
     * 缓存key, 通过 decr 方式扣减库存
     * @param cacheKey 缓存Key
     * @return 扣减结果
     */
    Boolean subtractionAwardStock(String cacheKey);

    /**
     * 缓存key, 通过 decr 方式扣减库存
     * @param cacheKey 缓存Key
     * @return 扣减结果
     */
    Boolean subtractionAwardStock(String cacheKey, Date endDateTime);

    /**
     * 写入奖品库存消费队列
     * 将一个 StrategyAwardStockKeyVO 对象放入一个延迟队列中，并设置延迟时间为 3 秒。
     * 3 秒后，该对象会被自动放入阻塞队列中，等待后续的处理逻辑
     * @param strategyAwardStockKeyVO 对象值对象 - 策略ID和奖品ID
     */
    void awardStockConsumeSendQueue(StrategyAwardStockKeyVO strategyAwardStockKeyVO);

    // 获取奖品库存消费队列
    StrategyAwardStockKeyVO takeQueueValue() throws InterruptedException;

    /**
     * 更新奖品库存消耗
     * @param strategyId 策略ID
     * @param awardId 奖品ID
     */
    void updateStrategyAwardStock(Long strategyId, Integer awardId);

    /**
     * 根据策略ID+奖品ID的唯一值组合，查询奖品信息
     * @param strategyId 策略ID
     * @param awardId    奖品ID
     * @return 奖品信息
     */
    StrategyAwardEntity queryStrategyAwardEntity(Long strategyId, Integer awardId);

    /**
     * 根据活动ID查询策略ID
     * @param activityId 活动ID
     * @return 策略ID
     */
    Long queryStrategyIdByActivityId(Long activityId);

    /**
     * 查询用户今日抽奖次数
     * @param userId
     * @param strategyId
     * @return
     */
    Integer queryTodayUserRaffleCount(String userId, Long strategyId);

    /**
     * 查询ruleLock的值 - 抽奖几次后解锁限制
     * @param treeIds
     * @return
     */
    Map<String, Integer> queryAwardRuleLockCount(String[] treeIds);


    /**
     * 查询奖品权重配置
     * @param strategyId 策略ID
     * @return 权重规则
     */
    List<RuleWeightVO> queryAwardRuleWeight(Long strategyId);

    /**
     * 查询用户已经抽奖的次数
     * @param userId
     * @param strategyId
     * @return
     */
    Integer queryActivityAccountTotalUseCount(String userId, Long strategyId);

}
